/*------------------------------------------------------------------------------
 * Copyright 2012 NCR Corporation
 *------------------------------------------------------------------------------
 * All revision information is updated automatically from source code control
 * change records - please do not manually edit.
 *------------------------------------------------------------------------------
 *
 * $LastChangedRevision:: 2026                                     $
 * $LastChangedBy:: rb250096                                       $
 * $LastChangedDate:: 2012-04-07 18:34:30 -0400 (Sat, 07 Apr 2012) $
 */

package com.ncr.nep.dashboardcore.rest.client;

import java.io.Serializable;

import com.google.gwt.core.client.GWT;
import com.google.web.bindery.autobean.shared.AutoBean;
import com.google.web.bindery.autobean.shared.AutoBeanCodex;
import com.google.web.bindery.autobean.shared.AutoBeanFactory;

/**
 * Exception that is used when a JSON object is returned in the body of an
 * HTTP error response.  The JSON object returned is expected to have two
 * properties: <code>message</code> and <code>code</code>.
 *
 * @author rb250096
 * @version $Revision: 2026 $
 */
public class JSONException extends Exception {

    //--------------------------------------------------------------------------
    //
    //  Inner classes
    //
    //--------------------------------------------------------------------------

    /**
     * Wrapped error object received from the server.
     */
    protected interface Error extends Serializable {
        /**
         * Gets the error message.
         *
         * @return The error message.
         */
        String getMessage();

        /**
         * Sets the error message.
         *
         * @param message The error message.
         */
        void setMessage(String message);

        /**
         * Gets the error code.
         *
         * @return The error code.
         */
        int getErrorCode();

        /**
         * Sets the error code.
         *
         * @param errorCode The error code.
         */
        void setErrorCode(int errorCode);
    }

    /**
     * Factory for generating error objects.
     */
    protected interface ErrorFactory extends AutoBeanFactory, Serializable {

        /**
         * Generates a new Error object.
         *
         * @return A new Error object.
         */
        AutoBean<Error> error();
    }

    //--------------------------------------------------------------------------
    //
    //  Fields
    //
    //--------------------------------------------------------------------------

    /**
	 * Serialization ID.
	 */
	private static final long serialVersionUID = 1L;

    /**
     * Factory used for generating {@link Error} objects.
     */
    protected static ErrorFactory errorFactory;

    /**
     * The error object deserialized from the server.
     */
    protected Error error;

    //--------------------------------------------------------------------------
    //
    //  Constructors
    //
    //--------------------------------------------------------------------------

    static {
        if(GWT.isClient()) {
            errorFactory = GWT.create(ErrorFactory.class);
        }
    }

    /**
     * Constructor
     *
     * @param json JSON string representing error from server returned in HTTP
     *             error response.
     */
    public JSONException(String json) {
        assert json != null : "JSON cannot be null";

        this.error = AutoBeanCodex.decode(errorFactory, Error.class, json).as();
    }

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    /**
     * Gets the error message describing the server-side error that occurred.
     *
     * @return The error message.
     */
    @Override
    public String getMessage() {
        return this.error.getMessage();
    }

    /**
     * Gets error code defining the server-side error that occurred.
     *
     * @return The error code.
     */
    public int getErrorCode() {
        return this.error.getErrorCode();
    }
}
